package com.anolesoft.yr.mbus.base.service.impl;

import com.anolesoft.yr.exception.ServiceException;
import com.anolesoft.yr.mbus.base.dto.BaseRegionDTO;
import com.anolesoft.yr.mbus.base.dto.BaseRegionTreeQueryDTO;
import com.anolesoft.yr.mbus.base.entity.BaseRegionDO;
import com.anolesoft.yr.mbus.base.entity.BaseRegionTreeQueryDO;
import com.anolesoft.yr.mbus.base.mapper.BaseRegionMapper;
import com.anolesoft.yr.mbus.base.mapper.BaseRegionTreeQueryMapper;
import com.anolesoft.yr.mbus.base.service.BaseRegionService;
import com.anolesoft.yr.mbus.crm.dto.CrmBaseDTO;
import com.anolesoft.yr.util.CommonUtils;
import com.anolesoft.yr.util.CustomBeanUtils;
import com.anolesoft.yr.util.PageData;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author zhj
 * @date 2020/8/7 19:17
 */
@Service("baseRegionServiceImpl")
public class BaseRegionServiceImpl implements BaseRegionService {
    @Autowired
    private BaseRegionMapper baseRegionMapper;
    @Autowired
    private BaseRegionTreeQueryMapper baseRegionTreeQueryMapper;

    private void checkUnique(BaseRegionDTO baseRegionDTO, boolean isModify) {
        String objuid = baseRegionDTO.getObjuid();
        String regionCode = baseRegionDTO.getRegionCode();
        String regionName = baseRegionDTO.getRegionName();
        if (isModify) {
            if (baseRegionMapper.checkUniqueForRegionCodeUpdate(regionCode, objuid) > 0) {
                throw new ServiceException("地区编码已存在");
            }
            if (baseRegionMapper.checkUniqueForRegionNameUpdate(regionName, objuid) > 0) {
                throw new ServiceException("地区名称名称已存在");
            }
        } else {
            if (baseRegionMapper.checkUniqueForRegionCode(regionCode) > 0) {
                throw new ServiceException("地区编码已存在");
            }
            if (baseRegionMapper.checkUniqueForRegionName(regionName) > 0) {
                throw new ServiceException("地区名称已存在");
            }
        }
    }
    @Transactional
    @Override
    public int create(BaseRegionDTO baseRegionDTO) {
        checkUnique(baseRegionDTO,false);
        return baseRegionMapper.insert(dto2do(baseRegionDTO));
    }

    @Transactional
    @Override
    public int modify(BaseRegionDTO baseRegionDTO) {
        checkUnique(baseRegionDTO,true);
        return baseRegionMapper.update(dto2do(baseRegionDTO));
    }

    @Transactional
    @Override
    public int remove(String id) {
        return baseRegionMapper.delete(id);
    }

    @Transactional
    @Override
    public int removeBatch(List<String> ids) {
        int res = 0;
        for (String id : ids) {
            res += baseRegionMapper.delete(id);
        }
        return res;
    }

    @Override
    public List<BaseRegionDTO> selectAll() {
        return baseRegionMapper.selectAll().stream().map(t -> CustomBeanUtils.baseRegionDO2DTO(t)).collect(Collectors.toList());
    }

    @Override
    public PageData<List<BaseRegionDTO>> selectAll(Integer limit, Integer curr) {
        Page<BaseRegionDO> page = new Page<>(curr, limit);
//        return baseRegionMapper.selectPageAll(page).stream().map(t -> do2dto(t)).collect(Collectors.toList());
        List<BaseRegionDO> baseRegionDOS = baseRegionMapper.selectPageAll(page);
        List<BaseRegionDTO> baseRegionDTOS = baseRegionDOS.stream().map(t -> CustomBeanUtils.baseRegionDO2DTO(t)).collect(Collectors.toList());
        return new PageData<>(((int) page.getTotal()), baseRegionDTOS);
    }

    @Override
    public Optional<BaseRegionDTO> selectOneById(String id) {
        BaseRegionDO baseRegionDO = baseRegionMapper.selectOneById(id);
        if (baseRegionDO != null) {
            return Optional.of(CustomBeanUtils.baseRegionDO2DTO(baseRegionDO));
        }
        return Optional.ofNullable(null);
    }

    @Override
    public List<BaseRegionDTO> selectListByName(String name) {
        return baseRegionMapper.selectListByName(CommonUtils.warpString(name)).stream().map(t -> CustomBeanUtils.baseRegionDO2DTO(t)).collect(Collectors.toList());
    }

    @Override
    public PageData<List<BaseRegionDTO>> selectPageByName(String name, Integer limit, Integer curr) {
        Page<BaseRegionDO> page = new Page<>(curr, limit);
//        return baseRegionMapper.selectPageByName(CommonUtils.warpString(name), page).stream().map(t -> do2dto(t)).collect(Collectors.toList());

        List<BaseRegionDO> baseRegionDOS = baseRegionMapper.selectPageByName(CommonUtils.warpString(name), page);
        List<BaseRegionDTO> baseRegionDTOS = baseRegionDOS.stream().map(t -> CustomBeanUtils.baseRegionDO2DTO(t)).collect(Collectors.toList());
        return new PageData<>(((int) page.getTotal()), baseRegionDTOS);
    }

    @Override
    public List<BaseRegionDTO> selectListByFactoryCode(String factoryCode) {
        return baseRegionMapper.selectListByFactoryCode(factoryCode).stream().map(t -> CustomBeanUtils.baseRegionDO2DTO(t)).collect(Collectors.toList());
    }

    @Override
    public PageData<List<BaseRegionDTO>> selectPageByFactoryCode(String factoryCode, Integer limit, Integer curr) {
        Page<BaseRegionDO> page = new Page<>(curr, limit);
//        return baseRegionMapper.selectPageByFactoryCode(factoryCode, page).stream().map(t -> do2dto(t)).collect(Collectors.toList());
        List<BaseRegionDO> baseRegionDOS = baseRegionMapper.selectPageByFactoryCode(CommonUtils.warpString(factoryCode), page);
        List<BaseRegionDTO> baseRegionDTOS = baseRegionDOS.stream().map(t -> CustomBeanUtils.baseRegionDO2DTO(t)).collect(Collectors.toList());
        return new PageData<>(((int) page.getTotal()), baseRegionDTOS);
    }


    @Override
    public List<BaseRegionDTO> selectListByCondition(BaseRegionDTO baseRegionDTO) {
        baseRegionDTO.setRegionCode( StringUtils.isEmpty(baseRegionDTO.getRegionCode()) ? null : CommonUtils.warpString(baseRegionDTO.getRegionCode()));
        baseRegionDTO.setRegionName(StringUtils.isEmpty(baseRegionDTO.getRegionName()) ? null : CommonUtils.warpString(baseRegionDTO.getRegionName()));
        baseRegionDTO.setRegionLevel(StringUtils.isEmpty(baseRegionDTO.getRegionLevel()) ? null : CommonUtils.warpString(baseRegionDTO.getRegionLevel()));
        return baseRegionMapper.selectListByCondition(dto2do(baseRegionDTO)).stream().map(t -> CustomBeanUtils.baseRegionDO2DTO(t)).collect(Collectors.toList());
    }

    @Override
    public PageData<List<BaseRegionDTO>> selectPageByCondition(BaseRegionDTO baseRegionDTO, Integer limit, Integer curr) {
        Page<BaseRegionDO> page = new Page<>(curr, limit);
        baseRegionDTO.setRegionCode( StringUtils.isEmpty(baseRegionDTO.getRegionCode()) ? null : CommonUtils.warpString(baseRegionDTO.getRegionCode()));
        baseRegionDTO.setRegionName(StringUtils.isEmpty(baseRegionDTO.getRegionName()) ? null : CommonUtils.warpString(baseRegionDTO.getRegionName()));
        baseRegionDTO.setRegionLevel(StringUtils.isEmpty(baseRegionDTO.getRegionLevel()) ? null : CommonUtils.warpString(baseRegionDTO.getRegionLevel()));
//        return baseRegionMapper.selectPageByCondition(BaseRegionDO.builder()
//                .parentUid(baseRegionDTO.getParentUid())
//                .regionName(baseRegionDTO.getRegionName())
//                .regionLevel(baseRegionDTO.getRegionLevel())
//                .regionCode(baseRegionDTO.getRegionCode())
//                .factoryCode(baseRegionDTO.getFactoryCode())
//                .build(), page).stream().map(t -> do2dto(t)).collect(Collectors.toList());
        List<BaseRegionDO> baseRegionDOS = baseRegionMapper.selectPageByCondition(BaseRegionDO.builder()
                .parentUid(baseRegionDTO.getParentUid())
                .regionName(baseRegionDTO.getRegionName())
                .regionLevel(baseRegionDTO.getRegionLevel())
                .regionCode(baseRegionDTO.getRegionCode())
                .factoryCode(baseRegionDTO.getFactoryCode())
                .build(), page);
        List<BaseRegionDTO> baseRegionDTOS = baseRegionDOS.stream().map(t -> CustomBeanUtils.baseRegionDO2DTO(t)).collect(Collectors.toList());
        return new PageData<>(((int) page.getTotal()), baseRegionDTOS);
    }

    @Override
    public List<BaseRegionDTO> findChildrenByParentUid(String parentUid) {
        return baseRegionMapper.findChildrenByParentUid(parentUid).stream().map(t -> CustomBeanUtils.baseRegionDO2DTO(t)).collect(Collectors.toList());
    }

    @Override
    public List<BaseRegionDTO> findTopLevel() {
        return baseRegionMapper.findTopLevel().stream().map(t -> CustomBeanUtils.baseRegionDO2DTO(t)).collect(Collectors.toList());
    }

    @Override
    public List<BaseRegionTreeQueryDTO> getTree(String parentId) {
        List<BaseRegionTreeQueryDO> baseRegionTreeQueryDOS = baseRegionTreeQueryMapper.selectTree(parentId);
//        List<BaseRegionTreeQueryDTO> baseRegionTreeQueryDTOs = new ArrayList<>(10);
//        for (BaseRegionTreeQueryDO baseRegionTreeQueryDO : baseRegionTreeQueryDOS) {
//            BaseRegionTreeQueryDTO baseRegionTreeQueryDTO = BaseRegionTreeQueryDTO.builder()
//                    .field(baseRegionTreeQueryDO.getRegionName())
//                    .id(baseRegionTreeQueryDO.getObjuid())
//                    .title(baseRegionTreeQueryDO.getRegionName())
//                    .build();
//            List<BaseRegionTreeQueryDTO> children = getChildren(baseRegionTreeQueryDO.getChildren());
//            baseRegionTreeQueryDTO.setChildren(children);
//            baseRegionTreeQueryDTOs.add(baseRegionTreeQueryDTO);
//        }
//        return baseRegionTreeQueryDTOs;
        return getChildren(baseRegionTreeQueryDOS);
    }

    private List<BaseRegionTreeQueryDTO> getChildren(List<BaseRegionTreeQueryDO> children) {
        return children.stream().map(t->{
            BaseRegionTreeQueryDTO baseRegionTreeQueryDTO = BaseRegionTreeQueryDTO.builder()
                    .field(t.getRegionName())
                    .id(t.getObjuid())
                    .title(t.getRegionName())
                    .pid(t.getParentUid())
                    .regionCode(t.getRegionCode())
                    .regionLevel(t.getRegionLevel())
                    .regionName(t.getRegionName())
                    .factoryCode(t.getFactoryCode())
                    .build();
            if(t.getChildren().size()>0){
                baseRegionTreeQueryDTO.setChildren( getChildren(t.getChildren()) );
            }else{
                baseRegionTreeQueryDTO.setChildren(new ArrayList<>(10));
            }
            return baseRegionTreeQueryDTO;
        }).collect(Collectors.toList());
    }


    private BaseRegionDO dto2do(BaseRegionDTO baseRegionDTO) {
        return BaseRegionDO.builder()
                .remark(baseRegionDTO.getRemark())
                .parentUid(StringUtils.isEmpty(baseRegionDTO.getParentUid()) ? "-" : baseRegionDTO.getParentUid())
                .modifyUserUid(baseRegionDTO.getModifyUserUid())
                .deleteFlag(baseRegionDTO.getDeleteFlag())
                .createUserUid(baseRegionDTO.getCreateUserUid())
                .regionCode(baseRegionDTO.getRegionCode())
                .regionLevel(baseRegionDTO.getRegionLevel())
                .regionName(baseRegionDTO.getRegionName())
                .factoryCode(baseRegionDTO.getFactoryCode())
                .objuid(baseRegionDTO.getObjuid())
                .build();
    }

//    private BaseRegionDTO do2dto(BaseRegionDO t) {
//        return BaseRegionDTO.builder()
//                .createTime(t.getCreateTime())
//                .createUserUid(t.getCreateUserUid())
//                .deleteFlag(t.getDeleteFlag())
//                .factoryCode(t.getFactoryCode())
//                .modifyTime(t.getModifyTime())
//                .modifyUserUid(t.getModifyUserUid())
//                .objuid(t.getObjuid())
//                .parentUid(t.getParentUid())
//                .regionCode(t.getRegionCode())
//                .regionLevel(t.getRegionLevel())
//                .regionName(t.getRegionName())
//                .remark(t.getRemark())
//                .build();
//    }
}
